// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Engine/DataTable.h"
#include "CombatGameCharacter.generated.h"

USTRUCT(BlueprintType)
struct FAttackMontage : public FTableRowBase {
	GENERATED_BODY()

	UPROPERTY(EditAnywhere)
	class UAnimMontage* Montage;
};

UENUM(BlueprintType)
enum class EAttackType :uint8 {
	PUNCH		UMETA(DisplayName = "Punch"),
	KICK				UMETA(DisplayName = "Kick"),
};

UCLASS(config=Game)
class ACombatGameCharacter : public ACharacter
{
	GENERATED_BODY()

	/** Camera boom positioning the camera behind the character */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class USpringArmComponent* CameraBoom;

	/** Follow camera */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
	class UCameraComponent* FollowCamera;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Animation, meta = (AllowPrivateAccess = "true"))
	UDataTable* AttackMontageDataTable;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Collision, meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* LeftAttackBox;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Collision, meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* RightAttackBox;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Audio, meta = (AllowPrivateAccess = "true"))
	USoundBase* AttackSound;

	class UAudioComponent* AttackAudioComp;

public:
	ACombatGameCharacter();

	/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
	float BaseTurnRate;

	/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
	float BaseLookUpRate;

	void OnAttackEnableChanged(bool Enable);

	void BeginPlay() override;

protected:

	/** Resets HMD orientation in VR. */
	void OnResetVR();

	/** Called for forwards/backward input */
	void MoveForward(float Value);

	/** Called for side to side input */
	void MoveRight(float Value);

	/** 
	 * Called via input to turn at a given rate. 
	 * @param Rate	This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
	 */
	void TurnAtRate(float Rate);

	/**
	 * Called via input to turn look up/down at a given rate. 
	 * @param Rate	This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
	 */
	void LookUpAtRate(float Rate);

	/** Handler for when a touch input begins. */
	void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);

	/** Handler for when a touch input stops. */
	void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);

	void Punch();

	void Kick();

	void Attack(EAttackType Type);

	bool bStandingMontagePlaying;

	void CrouchStart();

	bool bReady;

	void ReadyToFight();

	static const float ExitReadyTime;

	FTimerHandle ExitReadyTimer;

	void ExitReadyTimeout();
/*6*/#if 1
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float WalkingSpeed;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float RunningSpeedFactor;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float ReadyWalkingSpeedFactor;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float CrouchingSpeed;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float ReadyCrouchingSpeedFactor;

	bool bIsRunning;

	void RunStart();

	void RunEnd();

	void UpdateMovementProp();

	bool bTargetAttacked;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Movement)
	float AttackColdTime;

	FTimerHandle AttackColdTimer;
#endif
protected:
	// APawn interface
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
	// End of APawn interface

	UFUNCTION()
	void OnAttackHit(UPrimitiveComponent* HitComponent,
		AActor* OtherActor, UPrimitiveComponent* OtherComp,
		FVector NormalImpulse, const FHitResult& Hit);

public:
	/** Returns CameraBoom subobject **/
	FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
	/** Returns FollowCamera subobject **/
	FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }

	UFUNCTION(BlueprintCallable)
	FORCEINLINE bool GetStandingMontagePlaying() const { return bStandingMontagePlaying; }

	UFUNCTION(BlueprintCallable)
	FORCEINLINE bool GetIsReady() const { return bReady; }

};

